package api

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"path/filepath"
	_ "sync"
	. "pdpconv/model"
	. "pdpconv/util"
	"strconv"
	"strings"
	"time"
	"os"
)

var DataDir  *string
var ImageSuffix = ".png"


func IndexApi(c *gin.Context){
	c.HTML(http.StatusOK,"index.tmpl",gin.H{
		"title":"welcome to pdpconv",
	})
}

func ListData(c *gin.Context){
	c.HTML(http.StatusOK,"list.tmpl",gin.H{
		"title":"welcome to pdpconv",
	})
}

func Login(c *gin.Context){

	username := c.PostForm("username")
	password := c.PostForm("password")

	log.Printf("用户:[%v] passwd:[%v] login",username,password)
	if username == "admin" && password == "admin" {
		c.JSON(http.StatusOK,NewSuccResult2("token123"))

		//c.Redirect(http.StatusMovedPermanently,"res/list")
		return
	}
	c.JSON(http.StatusOK,NewFailedResult2(CODE_LOGIN_FAILED,"账号或密码错误！"))

}

func FindPageListApi(c *gin.Context){

	var pageNum int
	var pageSize = 20
	result := make([]Document,0)
	var paramError error

	var condition Document
	if er := c.ShouldBind(&condition); er != nil{
		log.Print(er.Error())
		c.JSON(http.StatusOK,NewFailedResult1("参数异常"))
		return
	}
	if pageNum,paramError = strconv.Atoi(c.PostForm("pageNum"));paramError != nil{
		pageNum = 1
	}

	if FindPageList(condition,pageNum,pageSize,&result) == nil {
		c.JSON(http.StatusOK, NewSuccResult2(result))
		return
	}
	c.JSON(http.StatusOK,NewFailedResult1("服务异常"))
}

func ShowDocImages(c *gin.Context){
	if id,err := strconv.Atoi(c.Param("id"));err != nil {
		c.JSON(http.StatusOK, NewFailedResult1("参数错误"))
	}else{
		var images []Image
		log.Println(id)
		if err = FindImages(uint(id),&images); err == nil{
			c.JSON(http.StatusOK, NewSuccResult2(images))
		}else{
			log.Panic(err)
			c.JSON(http.StatusOK,NewFailedResult1("服务异常"))
		}
	}
}

func ShowImage(c *gin.Context){
	if id,err := strconv.Atoi(c.Param("fileId"));err == nil {
		image := Image{}
		if err = GetImageByFileId(int64(id),&image); err != nil {
			c.JSON(http.StatusOK, NewFailedResult2(CODE_FAILED,"获取失败"))
			return
		}else{
			c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", image.Name))//fmt.Sprintf("attachment; filename=%s", filename)对下载的文件重命名
			c.Writer.Header().Add("Content-Type", "image/png")
			c.File(image.FilePath)
			//c.JSON(http.StatusOK, NewSuccResult2(image))
		}
	}else {
		c.JSON(http.StatusOK, NewFailedResult2(CODE_FAILED,"参数错误"))
	}
}

func UploadDoc(c *gin.Context){

	tag := c.PostForm("Tag")
	file, err := c.FormFile("file")
	if err != nil{
		c.JSON(http.StatusOK, NewFailedResult2(CODE_FAILED,"上传失败"))
		return
	}
	if file.Size> 50 * 1024 * 1024  {
		c.JSON(http.StatusOK, NewFailedResult2(CODE_FILE_MAX_FAILED,"上传文件超过限制"))
		return
	}
	fileName := filepath.Base(file.Filename)
	fileSuffic := filepath.Ext(fileName)
	fileId := FetchID()
	name := strings.TrimSuffix(fileName,fileSuffic)
	targetPath := *DataDir + string(filepath.Separator) +
		time.Now().Format("20060102") + string(filepath.Separator) +
		tag + string(filepath.Separator) +
		strconv.Itoa(int(fileId)) + string(filepath.Separator)
	if err:=os.MkdirAll(targetPath,os.ModePerm);err != nil {
		log.Panicln(err.Error())
		return
	}

	filePath := targetPath + fileName
	if err := c.SaveUploadedFile(file,filePath);err != nil {
		log.Println(err.Error())
		c.JSON(http.StatusOK, NewFailedResult2(CODE_FAILED,"保存文件失败"))
		return
	}
	var doc = Document{}
	doc.Name = name
	doc.FilePath = filePath
	doc.Tag = tag
	doc.Size = int(file.Size)
	doc.FileSuffix = fileSuffic
	doc.FileId = fileId
	doc.Status = TRANS_INIT
	if err = SaveDoc(&doc);err != nil {
		log.Println(err.Error())
		c.JSON(http.StatusOK, NewFailedResult2(CODE_FAILED,"保存记录失败"))
		return
	}
	imagesPath := make(map[int]string)
	if strings.ToLower(fileSuffic) == ".pdf" {
		// 转换文档
		imagesPath,err = PDFConvert(targetPath+fileName,ImageSuffix[1:],0,0,200,85)
	}else {
		// 转换文档
		imagesPath,err = LibreOfficeConvert(targetPath+fileName,ImageSuffix[1:],doc.FileId,0,0,200,85)
	}
	log.Println("转换结束：" + fileName)
	if err == nil {
		images := make([]*Image,0)
		for i,imagePath := range imagesPath {
			fileInfo,_ := os.Stat(imagePath)
			image := Image{
				Name: fileInfo.Name(),
				Size: int(fileInfo.Size()),
				PageNum: i,
				FilePath: imagePath,
				FileSuffix:ImageSuffix,
				FileId:FetchID(),
				DocId:doc.ID,
			}
			images = append(images,&image)
			SaveImage(&image)
		}
		//if err = SaveImages(images); err != nil {
		//	c.JSON(http.StatusOK, NewFailedResult2(CODE_FAILED,fileId +"保存图片失败"))
		//	return
		//}
		doc.PageSize = len(images)
		doc.Status = TRANS_END
		if err = UpdateDocStatusAndPageSize(doc.ID,len(images),TRANS_END); err != nil {
			c.JSON(http.StatusOK, NewFailedResult2(CODE_FAILED,"保存图片失败"))
			return
		}

		doc.Images = images
		c.JSON(http.StatusOK,NewSuccResult2(doc))
	}else {
		c.JSON(http.StatusOK, NewFailedResult2(CODE_FAILED,"转化失败"))
	}

}


// TODO 多文件上传
func UploadDocs(c *gin.Context){

	form,_ := c.MultipartForm()
	files := form.File["file"]

	for _, file := range files {
		log.Println(file.Filename)
		log.Print(file.Header.Get("Content-Type"))
		fileName := filepath.Base(file.Filename)
		c.SaveUploadedFile(file,*DataDir + "/" +fileName)
		var doc = Document{}
		doc.Name = fileName
		doc.FilePath = *DataDir
		doc.Tag = ""
		doc.Size = int(file.Size)
		SaveDoc(&doc)
	}

	c.JSON(http.StatusOK,NewSuccResult1(fmt.Sprintf("%d files uploaded!",len(files))))
}